﻿using Core.Framework.EntityExtend.AiExpression;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace Core.Framework.EntityExtend.Model
{
    /// <summary>
    /// EFCore实体映射关系
    /// [泛型缓存]
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class EFCoreModel<T> where T: class,new()
    {
        /// <summary>
        /// 缓存内容
        /// </summary>
        private static Mapping<T> mapping { get; set; }

        /// <summary>
        /// 映射关系
        /// </summary>
        /// <returns></returns>
        public static Mapping<T> GetModelMapping(DbContext context)
        {
            if (mapping == null)
            {
                mapping = new Mapping<T>();

                var entry = context.Entry(new T());

                // 获取TableName 名称
                foreach (var item in entry.Metadata.GetAnnotations())
                {
                    if (item.Name.Equals("Relational:TableName"))
                    {
                        mapping.tableName = (string)item.Value;
                        continue;
                    }
                }

                // 获取字段名
                foreach (var item in typeof(T).GetProperties())
                {

                    if (item.IsDefined(typeof(NotMappedAttribute), true))
                        continue;

                    PropertyEntry property = entry.Property(item.Name);

                    var filedParameter = new FiledParameter();

                    foreach (var annotation in property.Metadata.GetAnnotations())
                    {
                        switch (annotation.Name)
                        {
                            case "Relational:ColumnName":
                                filedParameter.name = (string)annotation.Value;
                                break;
                            case "SqlServer:ValueGenerationStrategy":
                                filedParameter.isIdentity = true;
                                break;
                        }
                    }

                    filedParameter.name = filedParameter.name ?? item.Name;

                    mapping.rows.TryAdd(item.Name, filedParameter);
                }
                
            }

            return mapping;
        }

    }

    /// <summary>
    /// 映射关系
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Mapping<T> where T : class
    {
        /// <summary>
        /// 表明
        /// </summary>
        public string tableName { get; set; }

        /// <summary>
        /// 字段和表对应关系
        /// </summary>
        public Dictionary<string, FiledParameter> rows { get; set; } = new Dictionary<string, FiledParameter>();
    }
}
